#include "stepmotor.h"

void MOTOR_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
#if 0
    RCC_APB2PeriphClockCmd(MOTOR_CLK, ENABLE );
    GPIO_InitStructure.GPIO_Pin = MOTOR_A|MOTOR_B|MOTOR_C|MOTOR_D;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStr ucture.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(MOTOR_PROT,&GPIO_InitStructure);
    GPIO_ResetBits(GPIOA, MOTOR_A|MOTOR_D|MOTOR_B|MOTOR_C);
#endif
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Pull = GPIO_NOPULL;
    GPIO_InitStructure.Pin = MOTOR_A | MOTOR_B | MOTOR_C | MOTOR_D;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(MOTOR_PROT, &GPIO_InitStructure);
}
extern uint32_t fac_us;
static void delay_us(uint32_t nus) // 100  6800
{
    uint32_t ticks;
    uint32_t told, tnow, tcnt = 0;
    uint32_t reload = SysTick->LOAD; // LOAD的值
    ticks = nus * fac_us;            // 计算延时需要计多少个数
    told = SysTick->VAL;             // 24  刚进入时的计数器值
    while (1)
    {
        tnow = SysTick->VAL; // 22  20  0
        if (tnow != told)
        {
            if (tnow < told)
                tcnt += told - tnow; // 这里注意一下SYSTICK是一个递减的计数器就可以了.
            else
                tcnt += reload - tnow + told;
            told = tnow;
            if (tcnt >= ticks)
                break; // 时间超过/等于要延迟的时间,则退出.
        }
    };
}
void delay_ms(uint16_t nms)
{
    uint32_t i;
    for (i = 0; i < nms; i++)
        delay_us(1000);
}

void MOTOR_Rhythm_4_1_4(uint8_t step, uint8_t dly)
{
    switch (step)
    {
    case 0:;
        ;
        break;

    case 1:
        MOTOR_A_LOW;
        MOTOR_B_HIGH;
        MOTOR_C_HIGH;
        MOTOR_D_HIGH; // 1
        break;

    case 2:
        MOTOR_A_HIGH;
        MOTOR_B_LOW;
        MOTOR_C_HIGH;
        MOTOR_D_HIGH; // 2
        break;

    case 3:
        MOTOR_A_HIGH;
        MOTOR_B_HIGH;
        MOTOR_C_LOW;
        MOTOR_D_HIGH; // 3
        break;

    case 4:
        MOTOR_A_HIGH;
        MOTOR_B_HIGH;
        MOTOR_C_HIGH;
        MOTOR_D_LOW; // 4
        break;
    }
    delay_ms(dly);
}

void MOTOR_Rhythm_4_2_4(uint8_t step, uint8_t dly)
{
    switch (step)
    {
    case 0:;
        ;
        break;

    case 1:
        MOTOR_A_LOW;
        MOTOR_B_HIGH;
        MOTOR_C_HIGH;
        MOTOR_D_LOW; // 1
        break;

    case 2:
        MOTOR_A_LOW;
        MOTOR_B_LOW;
        MOTOR_C_HIGH;
        MOTOR_D_HIGH; // 2
        break;

    case 3:
        MOTOR_A_HIGH;
        MOTOR_B_LOW;
        MOTOR_C_LOW;
        MOTOR_D_HIGH; // 3
        break;

    case 4:
        MOTOR_A_HIGH;
        MOTOR_B_HIGH;
        MOTOR_C_LOW;
        MOTOR_D_LOW; // 4
        break;
    }

    delay_ms(dly);
}

void MOTOR_Rhythm_4_1_8(uint8_t step, uint8_t dly)
{
    switch (step)
    {
    case 0:;
        ;
        break;

    case 1:
        MOTOR_A_LOW;
        MOTOR_B_HIGH;
        MOTOR_C_HIGH;
        MOTOR_D_HIGH; // 1
        break;

    case 2:
        MOTOR_A_LOW;
        MOTOR_B_LOW;
        MOTOR_C_HIGH;
        MOTOR_D_HIGH; // 2
        break;

    case 3:
        MOTOR_A_HIGH;
        MOTOR_B_LOW;
        MOTOR_C_HIGH;
        MOTOR_D_HIGH; // 3
        break;

    case 4:
        MOTOR_A_HIGH;
        MOTOR_B_LOW;
        MOTOR_C_LOW;
        MOTOR_D_HIGH; // 4
        break;

    case 5:
        MOTOR_A_HIGH;
        MOTOR_B_HIGH;
        MOTOR_C_LOW;
        MOTOR_D_HIGH; // 5
        break;

    case 6:
        MOTOR_A_HIGH;
        MOTOR_B_HIGH;
        MOTOR_C_LOW;
        MOTOR_D_LOW; // 6
        break;

    case 7:
        MOTOR_A_HIGH;
        MOTOR_B_HIGH;
        MOTOR_C_HIGH;
        MOTOR_D_LOW; // 7
        break;

    case 8:
        MOTOR_A_LOW;
        MOTOR_B_HIGH;
        MOTOR_C_HIGH;
        MOTOR_D_LOW; // 8
        break;
    }

    delay_ms(dly);
}

void MOTOR_Direction(uint8_t dir, uint8_t num, uint8_t dly)
{
    if (dir)
    {
        switch (num)
        {
        case 0:
            for (uint8_t i = 1; i < 9; i++)
            {
                MOTOR_Rhythm_4_1_8(i, dly);
            }
            break;
        case 1:
            for (uint8_t i = 1; i < 5; i++)
            {
                MOTOR_Rhythm_4_1_4(i, dly);
            }
            break;
        case 2:
            for (uint8_t i = 1; i < 5; i++)
            {
                MOTOR_Rhythm_4_2_4(i, dly);
            }
            break;
        default:
            break;
        }
    }
    else
    {
        switch (num)
        {
        case 0:
            for (uint8_t i = 8; i > 0; i--)
            {
                MOTOR_Rhythm_4_1_8(i, dly);
            }
            break;
        case 1:
            for (uint8_t i = 4; i > 0; i--)
            {
                MOTOR_Rhythm_4_1_4(i, dly);
            }
            break;
        case 2:
            for (uint8_t i = 4; i > 0; i--)
            {
                MOTOR_Rhythm_4_2_4(i, dly);
            }
            break;
        default:
            break;
        }
    }
}

void MOTOR_Direction_Angle(uint8_t dir, uint8_t num, uint16_t angle, uint8_t dly) 
{
    for (uint16_t i = 0; i < (64 * angle / 45); i++) // 64*64=4096 64*180=256 //512
    {
        MOTOR_Direction(dir, num, dly);
    }
}

void MOTOR_STOP(void)
{
    HAL_GPIO_WritePin(GPIOA, MOTOR_A | MOTOR_B | MOTOR_C | MOTOR_D, GPIO_PIN_RESET);
}
